/**
 * 
 */
package dms.model.util;

import java.util.Arrays;
import java.util.List;
import java.util.Iterator;
import java.util.NoSuchElementException;

/**
 * @author 李健
 *
 */
public class PageIterator<T> implements Iterator<T> {
	
	private T[] list;
	
	
	private Long allCount = 0L;
	
	private int currentIndex = -1;
	
	private int endIndex = -1;
	
	private int count = 0;
	
	private T nextElement = null;
	
	private T previousElement = null;

	private int startIndex;
	
	
	
	/**
	 * empty constructor
	 */
	public PageIterator() {
		super();
	}
	/**
	 * 没有实现暂时不用
	 * @param list
	 * @param allCount
	 * @param start
	 * @deprecated
	 */
/*	public PageIterator(List<T> list, int allCount, int start) {
		
	}*/
	/**
	 * 分页，这里的endIndex等于startIndex+count
	 * @param list 取出满足条件实体的一部分，list.size = count
	 * @param allCount 满足条件的全部实体数
	 * @param startIndex 在所有满足条件的实体中开始的索引值
	 * @param count 实际取出的实体数
	 */
	public PageIterator(List<T> list, Long allCount, int startIndex, int count) {
		this((T[]) list.toArray(), allCount, startIndex, count);
		
	}
	
	public PageIterator(T[] list, Long allCount, int startIndex, int count) {
		this.list = list;
		this.allCount = allCount;
		if (startIndex >= 0) {
			this.startIndex = startIndex;
		}
		currentIndex = -1;
		if (count != 0) {
			this.endIndex = count;
		} else {
			this.endIndex = allCount.intValue();
		}
		this.count = count;
		
	}

	/**
	 * @return the startIndex
	 */
	public int getStartIndex() {
		return startIndex;
	}
	/**
	 * @return the endIndex
	 */
	public int getEndIndex() {
		return endIndex;
	}
	@Override
	public boolean hasNext() {	
		if (currentIndex == endIndex) {
			return false;
		}
		
		if (nextElement == null) {
			nextElement = getNextElement();
			if (nextElement == null) {
				return false;
			}
		}
		return true;
	}

	@Override
	public T next() throws NoSuchElementException {
		T element = null;
		if (nextElement != null) {
			element = nextElement;
			nextElement = null;
		} else {
			element = getNextElement();
			if (element == null) {
				throw new NoSuchElementException();
			}
		}
		return element;
	}
	public T previous() throws NoSuchElementException {
		T element = null;
		if (previousElement != null) {
			element = previousElement;
			previousElement = null;
			
		} else {
			element = getPreviousElement();
			if (element == null) throw new NoSuchElementException();
		}
		return element;
	}

	/**
	 * @param allCount the allCount to set
	 */
	public void setAllCount(Long allCount) {
		this.allCount = allCount;
	}

	@Override
	public void remove() throws UnsupportedOperationException {		
	}
	
	/**
	 * 获取下一个元素
	 * @return
	 */
	private T getElement() {
		T element = null;
		if (currentIndex >= 0 && currentIndex < list.length) {
			element = list[currentIndex];
		} else {
			System.err.println("PageIterator Info: current index < 0 or currentIndex >= list.size ");
		}
		return element;
	}
	
	/**
	 * 前面是否还有元素
	 * @return
	 */
	public boolean hasPrevious() {
		if (currentIndex == 0) {
			return false;
		}
		if (previousElement == null) {
			previousElement = getPreviousElement();
			if (previousElement == null) {
				return false;
			}
			
		}
		return true;
	}
	/**
	 * 获得前一个元素
	 * @return
	 */
	private T getPreviousElement() {
		T element = null;
		while (currentIndex >= 0 && element == null) {
			currentIndex--;
			element = getElement();
		}
		return element;
	}
	
	private T getNextElement() {
		T element = null;
		if (currentIndex + 1 < endIndex && element == null) {
			currentIndex++;
			element = getElement();
		}
		return element;
	}
	
	public void reset() {
		list = null;
		nextElement = null;
		previousElement = null;
		startIndex = -1;
		currentIndex = -1;
		endIndex = -1;
		count = 0;
	}

	/**
	 * @return the list
	 */
	public List<T> getList() {
		return Arrays.asList(list);
	}

	/**
	 * @param list the list to set
	 */
	public void setList(T[] list) {
		this.list = list;
	}

	/**
	 * @return the currentIndex
	 */
	public int getCurrentIndex() {
		return currentIndex;
	}

	/**
	 * @param currentIndex the currentIndex to set
	 */
	public void setCurrentIndex(int currentIndex) {
		this.currentIndex = currentIndex;
	}

	/**
	 * @return the allCount
	 */
	public Long getAllCount() {
		return allCount;
	}

	/**
	 * @return the count
	 */
	public int getCount() {
		return count;
	}
	
	public int getSize() {
		return list.length;
	}
	
	
}
